#ifndef _NETWORK_MAXYIEYESPIMEDIATORCONTRE_INTERFACE_IEMEDIATOR_H_
#define _NETWORK_MAXYIEYESPIMEDIATORCONTRE_INTERFACE_IEMEDIATOR_H_

#include "rclcpp/rclcpp.hpp"
#include "Spi_Dev_Management/Spi_Buffer_Manager.h"
#include "Maxieye_Spi_Mediator_Contre/Ibuffer_User_Register.h"
#include <iostream>
#include <atomic>

// 获取某个变量在结构体中的位置
#define PARAM_OFFSET(Strct, Field)    ((unsigned long)&(((Strct *)0)->Field))

class Base_Mediator
{
public:
    Base_Mediator(const std::string& id, const uint16_t& pos_s_2_m, const size_t& len_s_2_m, const uint16_t& pos_m_2_s, const size_t& len_m_2_s);

    virtual ~Base_Mediator() = default;

    template<class T>
    void push_data(const T& send_data);
    template<class T>
    void read_data(T& recv_data);
    void register_soc_2_mcu_buffer(Ibuffer_User_Register* user_register);
    void register_mcu_2_soc_buffer(Ibuffer_User_Register* user_register);

private:
    std::string             its_id_name;
    uint16_t                its_begin_position_soc_2_mcu; //这个中介负责的起始位置
    size_t                  its_length_soc_2_mcu;
    uint16_t                its_begin_position_mcu_2_soc; //这个中介负责的起始位置
    size_t                  its_length_mcu_2_soc;
    Soc_Out_Data_Buffer*    its_soc_2_mcu_data_buffer_df;
    Soc_In_Data_Buffer*     its_mcu_2_soc_data_buffer_df;

    static rclcpp::Logger TRACE;
};

template<class T>
void Base_Mediator::push_data(const T& send_data)
{
    if(its_soc_2_mcu_data_buffer_df)
    {
        if(its_length_soc_2_mcu == sizeof(T))
        {
            its_soc_2_mcu_data_buffer_df->write_buffer(send_data, its_begin_position_soc_2_mcu);
        }
        else
        {
            RCLCPP_ERROR_STREAM(TRACE, "bad length : " << its_length_soc_2_mcu << " : " <<  sizeof(T));
        }
    }
}

template<class T>
void Base_Mediator::read_data(T& recv_data)
{
    if(its_mcu_2_soc_data_buffer_df)
    {
        if(its_length_mcu_2_soc == sizeof(T))
        {
            RCLCPP_INFO_STREAM(TRACE, "READ : " << its_begin_position_mcu_2_soc << "  " << its_length_mcu_2_soc);
            its_mcu_2_soc_data_buffer_df->read_buffer(its_begin_position_mcu_2_soc, recv_data);
        }
        else
        {
            RCLCPP_INFO_STREAM(TRACE, "bad length : " << its_length_mcu_2_soc << " : " <<  sizeof(T));
        }
    }
}

#endif